/** @file fft.h
 * @brief A master header file to define fft interfaces verion v0.0
 *
 * This is earlier implementation to benchmark 1D FFT. 
 */
#ifndef QMCPLUSPLUS_FFT_V0_MASTER_H
#define QMCPLUSPLUS_FFT_V0_MASTER_H
#include <config.h>
#include <complex>

#if !defined(HAVE_LIBFFTW)
const int FFTW_ESTIMATE=0;
const int FFTW_MEASURE=0;
const int FFTW_PATIENT=0;
typedef enum {FFTW_FORWARD = -1, FFTW_BACKWARD = 1 }fftw_direction; 
#endif

//namespace fft_v0 {

///enumeration to determine what FFT  engine is used
enum {FFTW_ENG=0  /*< FFTW  */
  , FFTESSL_ENG=1 /*< FFT ESSL */
  , FFTMKL_ENG=2  /* FFT MKL */
  , MAX_FFT_ENG /* size of this enum */
};

template<typename T1, typename T2>
struct is_complex2complex
{
  static const int value=1;
};

template<typename T>
struct is_complex2complex<T,std::complex<T> >
{
  static const int value=0;
};


//template<typename T>
//struct fft_data_traits
//{ };
//
//template<>
//struct fft_data_traits<double>
//{ 
//  typedef double real_type;
//  typedef double value_type;
//  typedef std::complex<double> complex_type;
//};
//
//template<>
//struct fft_data_traits<std::complex<double> >
//{ 
//  typedef double real_type;
//  typedef std::complex<double> value_type;
//  typedef std::complex<double> complex_type;
//};
//
//template<>
//struct fft_data_traits<float>
//{ 
//  typedef float value_type;
//  typedef float real_type;
//  typedef std::complex<float> complex_type;
//};
//
//template<>
//struct fft_data_traits<std::complex<float> >
//{ 
//  typedef float value_type;
//  typedef std::complex<float> real_type;
//  typedef std::complex<float> complex_type;
//};
struct fft_base
{
  int fft_size;
  int num_ffts;
  double timing[2];
  fft_base(int dims=0):fft_size(dims),num_ffts(1){}
  inline void resize(int dims, int howmany=1)
  {
    fft_size=dims;
    num_ffts=howmany;
  }
};

/** generic declaration of FFT_DFT
 *
 * @tparam PREC precision of the data
 * @tparam T  data type, real or complex
 * @tparam many true if multiple ffts is done.
 * @tparam eng enumration of the FFT library that is employed
 */
template<typename PREC, typename T, bool many, unsigned eng> 
struct FFT_DFT
{
//  int fft_size;
//  int num_ffts;
};

#if defined(HAVE_LIBFFTW)
#include <fft/v0/fftw_impl.h>
#endif

#if defined(HAVE_ESSL)
#include <fft/v0/essl_impl.h>
#endif

#if defined(HAVE_MKL)
#include <fft/v0/mkl_impl.h>
#endif
//}

#endif
